package datareportjson

import (
	"MqttCloudProtocolServer/ProtocolServer/mqttlib"
	"encoding/json"
	"strconv"
	"time"

	"MqttCloudProtocolServer/publiclib/datamodel/redismodel"
	"MqttCloudProtocolServer/publiclib/datastorage"

	"github.com/wonderivan/logger"
)

type MQTTFrameStructure struct {
	Receive  string `json:"receive"`
	Regstart uint16 `json:"regstart"`
	Addr     uint8  `json:"addr"`
	Iswrite  bool   `json:"iswrite"`
}
type MQTTDataStructure struct {
	Tag   string  `json:"tag"`
	Value float64 `json:"value"`
	Dis   string  `json:"dis"`
	Time  string  `json:"time"`
}
type MQTTReportData struct {
	Frame *MQTTFrameStructure  `json:"frame"`
	Data  []*MQTTDataStructure `json:"data"`
}
type MQTTReportInformation struct {
	Projectname    string            `json:"projectname"`
	Projectversion string            `json:"projectversion"`
	Fwversion      string            `json:"fwversion"`
	Cfgversion     string            `json:"cfgversion"`
	Writepoint     []string          `json:"writepoint"`
	Response       []*MQTTReportData `json:"response"`
}

// TCPServer TCP收发服务器
type DataReportAnalysis struct {
	mqttlib.OperatorBase
	mqttSender func(key string, buffer []uint8)
}

// 这里的callback是MQTT的发送函数
// 这是另一个外部线程控制的
func (_this *DataReportAnalysis) SetReceive(callback func(key string, buffer []uint8)) {
	_this.mqttSender = callback
}

// Start Fun
func (_this *DataReportAnalysis) Start() bool {
	return true
}

// Modify Fun
func (_this *DataReportAnalysis) Modify(params interface{}) bool {
	return true
}

// Close Fun
func (_this *DataReportAnalysis) Close() bool {
	return true
}

func (_this *DataReportAnalysis) redisReceive(tag string, value float64) bool {
	b := []byte("{\"tag\":\"" + tag + "\",\"value\":" + strconv.FormatFloat(value, 'f', -1, 64) + "}")
	_this.mqttSender(_this.GetKey(), b)
	return true
}

// SendData Fun
func (_this *DataReportAnalysis) SendData(buffer []uint8) bool {
	logger.Trace(string(buffer))
	res := new(MQTTReportInformation)
	if err := json.Unmarshal(buffer, res); err != nil {
		logger.Alert("上报报文错误-" + err.Error())
	} else {
		datas := res.Response
		for _, cpoint := range res.Writepoint {
			datastorage.GetRedisStorageContent().RegistCallback(cpoint, _this.redisReceive)
		}
		defer func() {
			if err := recover(); err != nil {
				logger.Alert(err)
			}
		}()
		if datas == nil {
			logger.Alert("datas nil " + strconv.Itoa(len(datas)))
			return true
		}
		for _, frame := range datas {
			if frame == nil || frame.Data == nil {
				logger.Alert("没有Frame:" + string(buffer))
				continue
			}
			for _, data := range frame.Data {
				if data == nil {
					logger.Alert("Frame中没有DATA:" + string(buffer))
					continue
				}
				t, err := time.Parse("", data.Time)
				if err != nil {
					t = time.Now()
				}
				datastorage.GetRedisStorageContent().SaveToRedis("realData", &redismodel.RealData{
					Key:      data.Tag,
					Value:    data.Value,
					ValueDis: data.Dis,
					LastTime: t,
				})
			}
		}
	}
	return true
}

// Delete Fun
func (_this *DataReportAnalysis) Delete() bool { return true }
